﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DesignByFarooq.PowershellByExample.Testing
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class MemoryStatusFileUnitTest
    {
        [TestMethod]
        public void PassNullInputToGetCollectionTime()  
        {
            Assert.IsNull(MemoryStatusFile.GetCollectionTime(null));
        }

        [TestMethod]
        public void PassEmptyInputToGetCollectionTime()
        {
            Assert.IsNull(MemoryStatusFile.GetCollectionTime(string.Empty));
        }

        [TestMethod]
        public void GetCollectionTime()
        {
            string line = "Start time: 2012-05-10T16:15:56.500";
            
            DateTime expectedDateTime = new DateTime(
                2012,
                5,
                10,
                16,
                15,
                56,
                500
                );

            DateTime? actualDateTime = MemoryStatusFile.GetCollectionTime(
                line
                );

            Assert.IsNotNull(
                actualDateTime
                );

            Assert.AreEqual(
                expectedDateTime,
                actualDateTime.Value
                );
        }

        [TestMethod]
        public void GetCollectionTimeWithInvalidData()
        {
            string line = "Start time: aaaa-bb-aaTaa:aa:aa.aaa";

            DateTime? actualDateTime = MemoryStatusFile.GetCollectionTime(
                line
                );

            Assert.IsNull(
                actualDateTime
                );

        }

        [TestMethod]
        public void GetCollectionTimeWithInvalidData2()
        {
            string line = "Start time: 9999-99-99T99:99:99.999";

            DateTime? actualDateTime = MemoryStatusFile.GetCollectionTime(
                line
                );

            Assert.IsNull(
                actualDateTime
                );

        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void PassNullInputToGetMemoryNodeObject()
        {
            MemoryStatusFile.GetMemoryNodeId(
                null
                );
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void PassEmptyInputToGetMemoryNodeObject()
        {
            MemoryStatusFile.GetMemoryNodeId(
                string.Empty
                );
        }

        [TestMethod]
        public void GetMemoryNodeId()
        {
            string input = "Memory node Id = 999                       KB";
            int expectedNodeId = 999;

            int? actualNodeId = MemoryStatusFile.GetMemoryNodeId(
                input
                );

            Assert.IsNotNull(
                actualNodeId
                );

            Assert.AreEqual(
                expectedNodeId, 
                actualNodeId.Value
                );
        }

        [TestMethod]
        public void GetMemoryNodeIdWithInvalidData()
        {
            string input = "Memory node Id = abc                       KB";
            
            int? actualNodeId = MemoryStatusFile.GetMemoryNodeId(
                input
                );

            Assert.IsNull(
                actualNodeId
                );
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void PassNullInputToGetNodeScopedObject()
        {
            MemoryStatusFile.GetNodeScopedObject(
                null
                );
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void PassEmptyInputToGetNodeScopedObject()
        {
            MemoryStatusFile.GetNodeScopedObject(
                string.Empty
                );
        }

        [TestMethod]
        public void GetNodeScopedObjectReturnsNull()
        {
            string input = "hello";

            Assert.IsNull(
                MemoryStatusFile.GetNodeScopedObject(input)
                );
        }

        [TestMethod]
        public void GetNodeScopedObject()
        {
            string input = "MEMORYCLERK_SQLBUFFERPOOL (node 999)       KB";

            Tuple<string, int> expectedTuple = new Tuple<string, int>(
                "MEMORYCLERK_SQLBUFFERPOOL",
                999
                );

            DesignByFarooq.PowershellByExample.Tuple<string, int> actualTuple = MemoryStatusFile.GetNodeScopedObject(
                input
                );

            Assert.AreEqual(
                expectedTuple,
                actualTuple
                );
        }

        [TestMethod]
        public void GetPartitions()
        {
            string inputFile = "dbcc_memorystatus.txt";

            IEnumerable<MemoryStatusFilePartition> partitions = MemoryStatusFile.GetPartitions(
                inputFile
                );

            Assert.IsNotNull(
                partitions
                );

            int expectedPartitionCount = 3;
            int actualPartitionCount = partitions.Count();

            Assert.AreEqual(
                expectedPartitionCount,
                actualPartitionCount
                );

        }

        [TestMethod]
        public void VerifyParitionIndexes()
        {
            string inputFile = "dbcc_memorystatus.txt";

            MemoryStatusFilePartitionCollection partitions = MemoryStatusFile.GetPartitions(
                inputFile
                );

            Assert.IsNotNull(
                partitions
                );

            int expectedPartitionCount = 3;
            int actualPartitionCount = partitions.Count();

            Assert.AreEqual(
                expectedPartitionCount,
                actualPartitionCount
                );

            Assert.AreEqual(
                56,
                partitions[0].StartOffset
                );

            Assert.AreEqual(
                0,
                partitions[0].EndOffset
                );

            Assert.AreEqual(
                46554,
                partitions[1].StartOffset
                );

            Assert.AreEqual(
                0,
                partitions[1].EndOffset
                );

            Assert.AreEqual(
                93048,
                partitions[2].StartOffset
                );

            Assert.AreEqual(
                0,
                partitions[2].EndOffset
                );
        }

        [TestMethod]
        public void FixEndOffsets()
        {
            string inputFile = "dbcc_memorystatus.txt";

            MemoryStatusFilePartitionCollection partitions = MemoryStatusFile.GetPartitions(
                inputFile
                );

            Assert.IsNotNull(
                partitions
                );

            int expectedPartitionCount = 3;
            int actualPartitionCount = partitions.Count();

            Assert.AreEqual(
                expectedPartitionCount,
                actualPartitionCount
                );

            Assert.AreEqual(
                56,
                partitions[0].StartOffset
                );

            Assert.AreEqual(
                0,
                partitions[0].EndOffset
                );

            Assert.AreEqual(
                46554,
                partitions[1].StartOffset
                );

            Assert.AreEqual(
                0,
                partitions[1].EndOffset
                );

            partitions.FixEndOffsets();

            Assert.AreEqual(
                56,
                partitions[0].StartOffset
                );

            Assert.AreEqual(
                46553,
                partitions[0].EndOffset
                );

            Assert.AreEqual(
                46554,
                partitions[1].StartOffset
                );

            Assert.AreEqual(
                93047,
                partitions[1].EndOffset
                );

            Assert.AreEqual(
                93048,
                partitions[2].StartOffset
                );

            Assert.AreEqual(
                139540,
                partitions[2].EndOffset
                );
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void PassNullInputFileToGetPartitions()
        {
            MemoryStatusFile.GetPartitions(
                null
                );
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void PassEmptyInputFileToGetPartitions()
        {
            MemoryStatusFile.GetPartitions(
                string.Empty
                );
        }
    }
}
